#pragma once

#include <iostream>
#include <memory>
#include <string>
#include <sys/wait.h>
#include <functional>
#include "Socket.hpp"
namespace TcpServerModule
{
    using namespace SocketModule;

    using tcphandler_t = std::function<bool(SockPtr, InetAddr)>; // 参数是客户端的文件描述符和客户端的IP和端口号
    // 只负责进行流式的IO，不对协议进行任何处理
    class TcpServer
    {
    public:
        TcpServer(int port) : _listensockp(std::make_unique<TcpSocket>()), _running(false), _port(port)
        {
            
        }
        void InitServer(tcphandler_t handler)
        {
            _handler = handler;
            _listensockp->BuildTcpSocket(_port); // 一次把套接字创建好
        }
        void Loop()
        {
            _running = true;
            while (_running)
            {
                // 1，accept
                InetAddr clientaddr;
                auto sockfd = _listensockp->Acceptor(&clientaddr); // 得到新的套接字,实际拿到的是一个TcpSocket的智能指针
                if (sockfd == nullptr)
                    continue;
                // 2,IO处理
                LOG(LogLevel::INFO) << "get a new client, info is: " << clientaddr.Addr();
                // _listensockp->Recv(sockfd);
                // _listensockp->Send(sockfd);
                pid_t id = fork();
                if (id == 0)
                {
                    _listensockp->Close();
                    if (fork() > 0)
                        exit(0);
                    _handler(sockfd, clientaddr);
                    exit(0);
                }
                sockfd->Close();
                waitpid(id, nullptr, 0);
            }
            _running = false;
        }
        ~TcpServer()
        {
            _listensockp->Close();
        }

    private:
        std::unique_ptr<Socket> _listensockp;
        bool _running;
        tcphandler_t _handler;
        int _port;
    };
}
